/**
 * config start
 */
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

const config = require('./config');

const { __DEV__, __PROD__ } = config.globals;
const APP_ENTRY = path.resolve(__dirname, './client/index.jsx');
let buildRunning = false;
let startTime = 0;


let cssLoader = [
    {
        loader: 'style-loader',
    },
    {
        loader: 'css-loader',//https://doc.webpack-china.org/loaders/css-loader/#importing
        options: {
            modules: true,
            importLoaders: 2,
            import: true,
            localIdentName: '[name]__[local]___[hash:base64:5]'
        },
    },
];

let cssLoaderWithoutModules = [
    {
        loader: 'style-loader',
    },
    {
        loader: 'css-loader',
        options: {
            import: true,
        }
    },
];

let lessLoader = [
    {
        loader: 'style-loader',
    },
    {
        loader: 'css-loader',
        options: {
            modules: true,
            import: true,
            localIdentName: '[name]__[local]___[hash:base64:5]'
        },
    },
    {
        loader: 'less-loader',
    },
];
let lessLoaderWithoutModules = [
    {
        loader: 'style-loader',
    },
    {
        loader: 'css-loader',
        options: {
            import: true,
        }
    },
    {
        loader: 'less-loader',
    }
];

if (!__DEV__) {
    cssLoader = ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
            {
                loader: 'css-loader',
                options: {
                    modules: true,
                    importLoaders: 2,
                    localIdentName: '[name]__[local]___[hash:base64:5]'
                },
            },
            {
                loader: 'less-loader',
            },
        ]
    });
    cssLoaderWithoutModules = ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
            {
                loader: 'css-loader',
            },
            {
                loader: 'less-loader',
            },
        ]
    });
    lessLoader = ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
            {
                loader: 'css-loader',
                options: {
                    modules: true,
                    localIdentName: '[name]__[local]___[hash:base64:5]'
                },
            },
            {
                loader: 'less-loader',
            },
        ],
    });
    lessLoaderWithoutModules = ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
            {
                loader: 'css-loader',
            },
        ],
    });
}

const webpackConfig = {
    entry: {
        app: __DEV__
            ? ['webpack-dev-server/client?http://127.0.0.1', 'webpack/hot/only-dev-server', 'babel-polyfill', APP_ENTRY]
            : [APP_ENTRY]
    },
    resolve: {
        modules: [
            path.join(__dirname, './client'),
            './',
            'node_modules',
        ],
        extensions: ['.web.js', '.js', 'json', '.jsx'],
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                use: [
                    'babel-loader'
                ],
                exclude: ['node_modules']
            },
            {
                test: /\.less$/,
                use: lessLoader,
                exclude: [/node_modules/],
            },
            {
                test: /\.css$/,
                use: cssLoader,
                exclude: [/node_modules/],
            },
            {
                test: /\.less$/,
                use: lessLoaderWithoutModules,
                include: [/node_modules/],
            },
            {
                test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=.*]+)?$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: 'fonts/[name].[ext]',
                    },
                }],
            },
            {
                test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=.*]+)?$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: 'fonts/[name].[ext]',
                    },
                }],
            },
            {
                test: /\.css$/,
                use: cssLoaderWithoutModules,
                include: [/node_modules/],
            },
            {
                test: /\.html/,
                use: [{
                    loader: 'html-loader',
                    options: {
                        minimize: false,
                    },
                }],
            },
            {
                test: /\.(jpg|png|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10000,
                        name: 'images/[name].[ext]'
                    },
                }],
            },
        ],
    },
    plugins: [
        // new webpack.DefinePlugin(config.globals),
        // new webpack.DefinePlugin({
        //     'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
        // })
        new webpack.ProgressPlugin({
            handler: (percentage, msg) => {
                const stream = process.stderr;

                if (!buildRunning) {
                    buildRunning = true;
                    startTime = new Date();
                } else if (stream.isTTY && percentage < 0.71) {
                    stream.cursorTo(0);
                    stream.write(` ${chalk.magenta(`${msg} ${Math.round(percentage * 100)}%`)}`);
                    stream.clearLine(1);
                } else if (percentage === 1) {
                    const now = new Date();
                    const buildTime = `${(now - startTime) / 1000}s`;
                    console.log(chalk.green(`\nwebpack: bundle build completed in ${buildTime}.`));

                    buildRunning = false;
                }
            },
        }),
    ],
};

if (__DEV__) {
    webpackConfig.output = {
        filename: 'js/[name].js',
        publicPath: '/',
    };
    webpackConfig.devtool = '#source-map';
    webpackConfig.plugins.push(
        new webpack.HotModuleReplacementPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['commons', 'manifest'],
            filename: 'js/[name].js',
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './client', 'index.html'),
            hash: false,
            filename: 'index.html',
            inject: 'body',
        })
    );
} else if (__PROD__) {
    webpackConfig.entry.commons = config.vendors;
    webpackConfig.entry.babel = ['babel-polyfill']
    webpackConfig.output = {
        filename: 'js/[name]-[chunkhash].js',
        chunkFilename: 'js/[name]-[chunkhash].js',
        path: path.resolve(__dirname, '../dist'),
        publicPath: './',
    };
    webpackConfig.devtool = '#source-map';
    webpackConfig.plugins.push(
        new webpack.optimize.CommonsChunkPlugin({
            names: ['commons', 'babel', 'manifest'],//同事babel打包，在不同的项目下，生成的名字是不一样的，同一个项目下，下面的filename路径变一下，名字也不一样
            filename: 'js/[name]-[chunkhash].js',
        }),
        new ExtractTextPlugin('css/[name].[contenthash].css', {
            allChunks: true,
        }),
        new webpack.HashedModuleIdsPlugin(),
        new UglifyJSPlugin({//https://doc.webpack-china.org/plugins/uglifyjs-webpack-plugin/
            sourceMap: true,//只有设置了devtool才会生效
            beautify: true,//2.x要放在这里
            uglifyOptions: {
                sourceMap: true,
                ie8: false,
                ecma: 8,
                parse: {},
                mangle: false,//不混淆名字
                output: {
                    comments: false,
                    beautify: true,//3.x要放这里
                    keep_quoted_props: true,
                },
                warnings: false,
                compress: {
                    keep_fnames: true,
                }
            }

        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './client', 'index.html'),
            hash: false,
            filename: 'index.html',
            inject: 'body',
        }),
        new BundleAnalyzerPlugin({
            // Can be `server`, `static` or `disabled`.
            // In `server` mode analyzer will start HTTP server to show bundle report.
            // In `static` mode single HTML file with bundle report will be generated.
            // In `disabled` mode you can use this plugin to just generate Webpack Stats JSON file by setting `generateStatsFile` to `true`.
            analyzerMode: 'static',
            // Host that will be used in `server` mode to start HTTP server.
            analyzerHost: '127.0.0.1',
            // Port that will be used in `server` mode to start HTTP server.
            analyzerPort: 8888,
            // Path to bundle report file that will be generated in `static` mode.
            // Relative to bundles output directory.
            reportFilename: path.resolve(__dirname, '../dist/report.html'),
            // Module sizes to show in report by default.
            // Should be one of `stat`, `parsed` or `gzip`.
            // See "Definitions" section for more information.
            defaultSizes: 'parsed',
            // Automatically open report in default browser
            openAnalyzer: true,
            // If `true`, Webpack Stats JSON file will be generated in bundles output directory
            generateStatsFile: true,
            // Name of Webpack Stats JSON file that will be generated if `generateStatsFile` is `true`.
            // Relative to bundles output directory.
            statsFilename: 'js/stats.json',
            // Options for `stats.toJson()` method.
            // For example you can exclude sources of your modules from stats file with `source: false` option.
            // See more options here: https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
            statsOptions: null,
            // Log level. Can be 'info', 'warn', 'error' or 'silent'.
            logLevel: 'info'
        })
    );
}

module.exports = webpackConfig;
